home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / UTILITY / CMDED2E6.ARJ / HISTORY.ASM < prev    next >
Assembly Source File  |  1992-06-30  |  10KB  |  403 lines

  1. ; HISTORY.ASM
  2. ; (c) 1989, 1990 Ashok P. Nadkarni
  3. ;
  4. ; This module implements the history feature of the cmdedit program.
  5. ; DFA stopped lines of length less than min_length being stored on stack
  6. ; (December 1990).
  7. ; WD made history stack cyclic and allowed display of current history.
  8.  
  9.     INCLUDE    common.inc
  10.     INCLUDE    buffers.inc
  11.  
  12.     PUBLIC    hist_top
  13.     PUBLIC    hist_init
  14.     PUBLIC    hist_fwd
  15.     PUBLIC    hist_back
  16.     PUBLIC    hist_fwd_match
  17.     PUBLIC    hist_bck_match
  18.     PUBLIC    remember
  19.     PUBLIC    hist_type
  20.     PUBLIC    execute_auto_recall
  21.     PUBLIC    execute_rsthist
  22.     PUBLIC    execute_histstat
  23.     PUBLIC    hist_ptr
  24.     PUBLIC    history
  25.  
  26. CSEG    SEGMENT    PARA PUBLIC 'CODE'
  27.  
  28.  
  29.     EXTRN    linebuf:BYTE        ;line buffer
  30.     EXTRN    lastchar:WORD
  31.     EXTRN    dot:WORD        ;current position in line buffer
  32.     EXTRN    min_length:WORD     ;added by dfa
  33.  
  34.  
  35. ; The history stack is maintained as a string stack using the functions in
  36. ; the string stack library. The top and bottom of the stack are always
  37. ; zero length strings (the bottom is always a zero length sentinel
  38. ; implemented by the string stack package but the top is explicitly 
  39. ; maintained by the history code.
  40. history    $string_stack 2 DUP (<>)    ;Buffer descriptors
  41. hist_ptr    DW    ?        ;Ptr to current buffer descriptor
  42.  
  43. DGROUP    GROUP    CSEG
  44.  
  45.     EXTRN    bell:PROC
  46.     EXTRN    set_disp_marks:PROC
  47.     EXTRN    erase_to_dot:PROC
  48.  
  49.     ASSUME    CS:DGROUP,DS:DGROUP,ES:DGROUP,SS:DGROUP
  50.  
  51.  
  52. ;+
  53. ; FUNCTION : hist_init
  54. ;
  55. ; Initializes the various data structures associated with the
  56. ; command history buffers. CALLER MUST ENSURE PASSED ADDRESSES ARE VALID
  57. ; AND BUFFER IS LARGE ENOUGH.
  58. ;
  59. ; Parameters:
  60. ;    AX     - length of buffer in bytes
  61. ;    BX    - address of buffer
  62. ;    CX    - 0 if DOS buffer, any other value if application buffer
  63. ; Returns:
  64. ;    Nothing.
  65. ; Registers destroyed : BX,CX
  66. ;-
  67. hist_init proc    near
  68.     push    bx
  69.     mov    bx,offset DGROUP:history ;bx := address of buffer descriptors
  70.     jcxz    @hist_init_1        ;if DOS, bx OK
  71.     add    bx,TYPE $string_stack    ;else point to application descriptor
  72. @hist_init_1:
  73.     xchg    ax,cx            ;CX = buffer size
  74.     pop    ax            ;AX = Buffer address
  75.                     ;BX points to appropriate descriptor
  76.     call    near ptr strstk_init    ;Initialize buffer and descriptor
  77.     xor    al,al            ;Push a zero length string onto stack
  78.     mov    cl,1            ;Force onto stack
  79.     call    near ptr strstk_push    ;Assumes no errors
  80.     ret
  81. hist_init    endp
  82.  
  83.  
  84. ;+
  85. ; FUNCTION : execute_rsthist
  86. execute_rsthist proc    near
  87.     mov    bx,offset DGROUP:history ;bx := address of buffer descriptors
  88.     jcxz    @execute_rsthist_1    ;if DOS, bx OK
  89.     add    bx,TYPE $string_stack    ;else point to application descriptor
  90. @execute_rsthist_1:
  91.     call    near ptr strstk_reset    ;Initialize buffer and descriptor
  92.     xor    al,al            ;Push a zero length string onto stack
  93.     mov    cl,1            ;Force onto stack
  94.     call    near ptr strstk_push    ;Assumes no errors
  95.     ret
  96. execute_rsthist    endp
  97.  
  98.  
  99.  
  100. ;+
  101. ; FUNCTION : hist_type
  102. ;
  103. ;    Sets the hist_ptr global to point at the descriptor for the
  104. ;    current caller (DOS or application).
  105. ;
  106. ; Parameters:
  107. ;    CX =    0 if DOS, anything else for application
  108. ;
  109. ; Returns:
  110. ;    Nothing.
  111. ; Registers destroyed : BX
  112. ;-
  113. hist_type proc near
  114.     mov    bx,offset DGROUP:history ;address of first descriptor
  115.     mov    hist_ptr,bx
  116.     ret
  117. hist_type endp
  118.  
  119.  
  120. ;+
  121. ; FUNCTION : hist_top
  122. ;
  123. ;    Resets the history pointer to the null string at top of history stack.
  124. ;    The line buffer itslef is NOT changed.
  125. ; Parameters:
  126. ;    None.
  127. ;
  128. ; Returns:
  129. ;    Nothing.
  130. ; Registers destroyed:  BX
  131. ;-
  132. hist_top proc near
  133.     mov    bx,hist_ptr        ;Point to current descriptor
  134.     call    near ptr strstk_settop    ;Set to top of history stack.
  135.  
  136.     ret
  137. hist_top endp
  138.  
  139.  
  140. ;+
  141. ; FUNCTION : hist_back
  142. ;
  143. ;    Gets the previous history line (if there is one) and stores it
  144. ;    in the line buffer. Also makes it the current line.
  145. ;
  146. ; Parameters:
  147. ;    None.
  148. ;
  149. ; Returns:
  150. ;    Nothing.
  151. ; Registers destroyed: AX,BX,CX
  152. ;-
  153. hist_back proc near
  154.     mov    dot,offset DGROUP:linebuf
  155.     jmp    hist_bck_match        ;Will return to caller
  156. hist_back endp
  157.  
  158.  
  159.  
  160. ;+
  161. ; FUNCTION : hist_fwd
  162. ;
  163. ;    Gets the next history line (if there is one) and stores it
  164. ;    in the line buffer. Also makes it the current line.
  165. ;
  166. ; Parameters:
  167. ;    None.
  168. ;
  169. ; Returns:
  170. ;    Nothing.
  171. ; Registers destroyed :
  172. ;-
  173. hist_fwd proc near
  174.     mov    dot,offset DGROUP:linebuf
  175.     jmp    hist_fwd_match        ;Will return to caller
  176. hist_fwd endp
  177.  
  178.  
  179.  
  180. ;+
  181. ; FUNCTION : hist_copy
  182. ;
  183. ;    Copies the current history line into the line buffer. The dot
  184. ;    is set to the beginning of the line.
  185. ;
  186. ; Parameters:
  187. ;    None.          (fixed these comments -- wd)
  188. ;
  189. ; Returns:
  190. ;    Nothing.
  191. ;    Sets lastchar to end of new history line.
  192. ;
  193. ; Registers destroyed: AX,BX,CX,DX
  194. ;-
  195. hist_copy proc near
  196.     mov    bx,hist_ptr    ;Current descriptor
  197.     mov    ax,offset DGROUP:linebuf ;the history line storage
  198.     push    ax        ;Remember
  199. ;    mov    dot,ax    ;Cursor will be at the beginning of line (removed--wd)
  200.     xchg    ax,dx        ;dx->first char in line (parameter)
  201.     mov    ax,lastchar    ;ax->upper limit (parameter)
  202.     call    near ptr set_disp_marks ;Indicate changed range
  203.                 ;No registers destroyed
  204.     mov    ax,dx        ;Restore beginning of line
  205.     mov    cx,LINEBUF_SIZE    ;cx<-max length of line (fixed this -- wd)
  206.     push    cx        ;Save it
  207.     call    near ptr strstk_copy ;Copy history line into linebuf
  208.                 ;AX == length of history string
  209.     pop    cx        ;
  210.     jnc    @hist_copy_90    ;Jump if no error from strstk_copy
  211.     call    near ptr bell    ;History line too long for buffer
  212.     mov    ax,cx        ;Number of bytes = max length of line
  213. @hist_copy_90:
  214.     pop    dx        ;dx->beginning of line
  215.     add    ax,dx        ;ax->end
  216.     mov    lastchar,ax    ;Update end of line
  217.     call    near ptr set_disp_marks ;Indicate changed range
  218.     ret
  219. hist_copy endp
  220.  
  221.  
  222.  
  223. ;+
  224. ; FUNCTION : remember
  225. ;
  226. ;    Saves the line buffer in the history area. If the line already
  227. ;    exists, it is moved to the top of the stack.
  228. ;   Added by dfa:  lines less than min_length are ignored.
  229. ;
  230. ; Parameters:
  231. ;    None.
  232. ;
  233. ; Returns:
  234. ;    Nothing.
  235. ;
  236. ; Registers destroyed:
  237. ;    AX,BX,CX,DX
  238. ;-
  239. remember proc near
  240.     mov    bx,hist_ptr        ;Descriptor
  241.     call    near ptr strstk_settop    ;Reset stack pointer
  242.     mov    ax,offset DGROUP:linebuf ;AX->line to be stored
  243.     mov    cx,lastchar
  244.     sub    cx,ax            ;CX<-length of line
  245.     cmp    cx,min_length        ;these two lines added by dfa
  246.     jb    @remember_20         ;ignore request if line too short
  247.     call    near ptr strstk_bck_find ;Look for it in history
  248. ;                      buffer. Note that if it is a
  249. ;                      null string, the sentinel at
  250. ;                      top of the stack is not found
  251. ;                      which is at it should be.
  252.     jc    @remember_10        ;Not in stack
  253.     call    near ptr strstk_kill    ;If found delete it from stack
  254. @remember_10:
  255.     call    near ptr strstk_settop    ;Point to sentinel at top of stack
  256.     call    near ptr strstk_kill    ;Delete it
  257.     mov    dx,offset DGROUP:linebuf ;String to be remembered
  258.     mov    ax,lastchar        ;Length of string
  259.     sub    ax,dx            ;AX(AL)<-length of string
  260.     mov    cl,1            ;Force the push
  261.     call    near ptr strstk_push    ;ignore success/fail status
  262.     xor    ax,ax            ;Zero length sentinel
  263.     mov    cl,1
  264.     call    near ptr strstk_push    ;Push it
  265. @remember_20:                ; label added by dfa
  266.     ret
  267. remember endp
  268.  
  269.  
  270.  
  271. ;+
  272. ; FUNCTION : hist_fwd_match, hist_bck_match
  273. ;
  274. ;    Looks fwd/back thru the history buffer starting from the current
  275. ;    history location looking for a line whose first n chracters match
  276. ;    the n characters before the current position in the line buffer.
  277. ;
  278. ; Parameters:
  279. ;    None.
  280. ;
  281. ; Returns:
  282. ;    CF    = 0 if match found
  283. ;          1 if no match
  284. ;
  285. ; Registers destroyed:
  286. ;-
  287. hist_match proc near
  288. hist_fwd_match LABEL near
  289.     mov    dx,offset DGROUP:strstk_fwd_match
  290.  
  291. ; wd added following 10 lines
  292.     mov    bx,hist_ptr
  293.     mov    ax,[bx].cur
  294.     cmp    ax,[bx].top    ;If the history pointer is at the end,
  295.     jne    @hist_match_10
  296.     mov    ax,[bx].low_end    ;reset it to the start before going forward
  297.     inc    ax
  298.     mov    [bx].cur,ax    ;Set current pointer
  299.     push    dx
  300.     call    near ptr bell
  301.     pop    dx
  302.  
  303.     jmp    short @hist_match_10
  304. hist_bck_match label near
  305.     mov    dx,offset DGROUP:strstk_bck_match
  306. @hist_match_10:  ; (wd reorganized this section)
  307.     mov    bx,hist_ptr    ;Descriptor address
  308.     mov    ax,offset DGROUP:linebuf ;start of pattern
  309.     mov    cx,dot        ;Current position in linebuffer
  310.     sub    cx,ax        ;Number of chars to match
  311.     push    cx        ;Save
  312.     call    dx        ;Will set CF if no match, else sets
  313.                 ; 'current' to matched string & AX to len
  314.     pop    cx        ;Restore count
  315.     jc    @hist_match_20    ;No match
  316.  
  317.     cmp    ax,cx       ;Line must be longer than the search string
  318.     je    @hist_match_10    ;...otherwise, try again (wd)
  319.     call    near ptr hist_copy ;Copy and display the history line
  320.     clc            ;Indicate we matched
  321.     jmp    short @hist_match_99 ; exit
  322.  
  323. @hist_match_20:
  324.     mov    ax,lastchar    ;AX->end-of-line
  325.     call    erase_to_dot    ;Else delete remaining chars in the
  326. ;                 line (chars between AX and dot)
  327.     stc            ;Indicate no match
  328. @hist_match_99:
  329.     ret
  330. hist_match endp
  331.  
  332.  
  333.  
  334. ;+
  335. ; FUNCTION : execute_auto_recall
  336. ;
  337. ;    This function looks backward through the history buffer for a
  338. ;    line with a prefix that matches the characters to the left of
  339. ;    the dot. The search begins with the CURRENT history line. ie.
  340. ;    if the current history line has a matching prefix, the current
  341. ;    pointer is not changed. If no match is found, the history stack
  342. ;    is reset.
  343. ;
  344. ; Parameters:
  345. ;    None.
  346. ;
  347. ; Returns:
  348. ;    CF    = 0 if match found
  349. ;          1 if no match
  350. ; Register(s) destroyed:
  351. ;    AX,BX,CX,DX
  352. ;-
  353. execute_auto_recall proc near
  354.     mov    bx,hist_ptr        ;BX->current history stack descriptor
  355.     mov    ax,offset DGROUP:linebuf ;AX->pattern
  356.     mov    cx,dot
  357.     sub    cx,ax            ;CX<-length of pattern
  358.     call    near ptr strstk_prefix    ;Current history line matches?
  359.     jne    @execute_auto_recall_50    ;No
  360.     clc                ;Yes, current line matches
  361.     jmp    short @execute_auto_recall_99
  362.  
  363. @execute_auto_recall_50:
  364.     call    near ptr hist_bck_match    ;Search backward
  365.     jnc    @execute_auto_recall_99    ;Found a match
  366. ;    No match, reset history stack pointer
  367.     mov    bx,hist_ptr        ;BX->current history stack descriptor
  368.     call    near ptr hist_top    ;Reset history stack
  369.     stc                ;Indicate no match
  370. @execute_auto_recall_99:
  371.     ret
  372. execute_auto_recall endp
  373.  
  374.  
  375. ;+
  376. ; FUNCTION : execute_histstat by wd
  377. ;
  378. ;    This function outputs the entire history buffer from oldest to newest.
  379. ;
  380. ; Parameters:
  381. ;    SI  -> first char in linebuf following this command
  382. ;    CX  == remaining num chars in the line
  383. ;
  384. ; Returns:
  385. ;    Nothing.
  386. ;
  387. ; Register(s) destroyed:
  388. ;    AX,BX,CX,DX
  389. ;-
  390. execute_histstat proc near
  391.     mov    bx,hist_ptr    ;BX->history stack descriptor
  392.     call    near ptr strstk_output
  393.     ret
  394. execute_histstat endp
  395.  
  396. CSEG    ENDS
  397.  
  398.     END
  399.